home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PACKET / CBBS60SO.ZIP / MBNODES.C < prev    next >
Text File  |  1989-02-05  |  9KB  |  463 lines

  1.  
  2. /*
  3.  *  MBNODES.C - 10/22/87 - Grab routes from NET/ROM
  4.  *  NN port call time file
  5.  */
  6.  
  7. #include "mb.h"
  8.  
  9. #if nncmd
  10.  
  11. #define ntout 3    /* "got all data" timeout */
  12.  
  13. short nodetime;
  14. PORTS *was;
  15. char  *mp;
  16. short nodedone;
  17.  
  18. /*
  19.  *  Node definition record.
  20.  *  One of these for each node found.
  21.  */
  22.  
  23. #define no_visit  0x01  /* Node has been visited */
  24. #define no_reach  0x02  /* Node can be reached   */
  25. #define no_busy   0x08  /* Node was busy         */
  26.  
  27. typedef struct NODE_S
  28. {
  29.   char *call;           /* Call of this node          */
  30.   char *name;
  31.   byte state;           /* "visited" "can be reached" */
  32.   byte hops;            /* Distance to this node      */
  33.   struct NODE_S *found; /* Where we were when we found a path to this one */
  34.   struct NODE_S *seen;  /* Where we were when we found this one */
  35.   struct NODE_S *next;  /* Next node                  */
  36. } NODE;
  37.  
  38. NODE *nodehd;
  39. NODE *nodetl;
  40. int  nodecnt;
  41. NODE *path[8];
  42. int  np;
  43.  
  44. /*
  45.  *  Find a node.
  46.  */
  47.  
  48. NODE *findnode(cp)
  49. char *cp;
  50. {
  51.   register NODE *n;
  52.  
  53.   for (n = nodehd; n isnt NULL; n = n->next) if (match(cp, n->call)) return n;
  54.   return NULL;
  55. }
  56.  
  57. /*
  58.  *  Find an unvisited node.
  59.  *  The one with the lowest cost path from the node we are at.
  60.  */
  61.  
  62. findunode()
  63. {
  64.  
  65.   register int  h;
  66.   register NODE *n;
  67.  
  68. /*
  69.  *  Find node at min hops not yet visited.
  70.  */
  71.  
  72.   if (nodedone) return false;
  73.  
  74.   h = 256;
  75.   path[0] = NULL;
  76.   for (n = nodehd; n isnt NULL; n = n->next)
  77.   {
  78.     if (n->state & no_reach) if (!(n->state & no_visit))
  79.     if (n->hops < h)
  80.     {
  81.       h = n->hops;
  82.       path[0] = n;
  83.     }
  84.   }
  85.  
  86.   if (path[0] is NULL) return false;
  87.  
  88.   for (np = 0; np < 7; np++)
  89.   {
  90.     if (path[np]->found is NULL) return false;
  91.     if (path[np]->found is nodehd) return true;
  92.     path[np + 1] = path[np]->found;
  93.   }
  94.   return false;
  95. }
  96.  
  97. /*
  98.  *  Add a node.
  99.  */
  100.  
  101. NODE *addnode(tp)
  102. char *tp;
  103. {
  104.   register NODE *n;
  105.   register char *cp;
  106.   register char *np;
  107.  
  108.   cp = tp;
  109.   np = tp;
  110.   for (; *tp; tp++) if (*tp is ':')
  111.   {
  112.     *tp = '\0';
  113.     cp = tp + 1;
  114.   }
  115.  
  116.   if ((n = findnode(cp)) isnt NULL)
  117.   {
  118.     if (n->name is NULL) if (np isnt cp)
  119.     {
  120.       n->name = (char *)mp; mp += (strlen(np) + 1);
  121.       strcpy(n->name, np);
  122.     }
  123.     return n;
  124.   }
  125.  
  126.   nodecnt++;
  127.  
  128.   n = (NODE *)mp; mp += sizeof(NODE);
  129.   n->call = (char *)mp; mp += (strlen(cp) + 1);
  130.   strcpy(n->call, cp);
  131.  
  132.   if (np is cp) n->name = NULL; else
  133.   {
  134.     n->name = (char *)mp; mp += (strlen(np) + 1);
  135.     strcpy(n->name, np);
  136.   }
  137.  
  138.   n->state = 0;
  139.   n->hops  = 255;
  140.   n->found = NULL;
  141.   n->seen  = NULL;
  142.   n->next  = NULL;
  143.   if (nodehd is NULL) nodehd = n; else nodetl->next = n;
  144.   nodetl   = n;
  145.   return n;
  146. }
  147.  
  148. /*
  149.  *  Connect to the local NET/ROM node.
  150.  */
  151.  
  152. clnode()
  153. {
  154.   port->mode = remote;
  155.   outstr("C "); outstr(nodehd->call); outchar('\n');
  156.   waitcmd();
  157.   do
  158.   {
  159.     if (!getit(nodetime))
  160.     {
  161.      if (!(port->mode & idle)) distnc();
  162.      port->mode = idle;
  163.      return;
  164.     }
  165.   }
  166.   while (!iscon(port->line));
  167. }
  168.  
  169. /*
  170.  *  Connect to a distant node, using NET/ROM.
  171.  */
  172.  
  173. cnode()
  174. {
  175.   register int i;
  176.  
  177.   path[0]->state setbit no_visit;
  178.   for (i = np; i >= 0; i--)
  179.   {
  180.     outstr("C "); outstr(path[i]->call); outchar('\n');
  181.     if (getit(path[i]->hops * nodetime))
  182.     {
  183.       if (!match(port->fld[1], "CONNECTED"))
  184.       {
  185.         if (!(port->mode & idle)) distnc();
  186.         port->mode = idle;
  187.         return false;
  188.       }
  189.     }
  190.     else
  191.     {
  192.       if (!(port->mode & idle)) distnc();
  193.       port->mode = idle;
  194.       return false;
  195.     }
  196.   }
  197.   return true;
  198. }
  199.  
  200. /*
  201.  *  Get the known nodes, links, and paths to them from THIS node.
  202.  */
  203.  
  204. getnode()
  205. {
  206.   register int i;
  207.   register int ti;
  208.   short base;
  209.   short tcnt;
  210.   NODE *temp[64];
  211.   NODE *via;
  212.  
  213.   fprintf(was->fl, "\nAt Node: %s\n", path[0]->call);
  214.  
  215.   outstr("p\n");
  216.   if (!getit(path[0]->hops * nodetime))
  217.   {
  218.     if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
  219.     if (!(port->mode & idle)) distnc();
  220.     port->mode = idle;
  221.     return false;
  222.   }
  223.   fprintf(was->fl, "\nParams: %s", port->line);
  224.   while (getit(ntout)) fprintf(was->fl, "Params: %s", port->line);
  225.  
  226. /*
  227.  *  Get the nodes known to this node.
  228.  */
  229.  
  230.   outstr("n *\n");
  231.  
  232. /*
  233.  *  Get line "Nodes ..."
  234.  */
  235.  
  236.   if (!getit(path[0]->hops * nodetime))
  237.   {
  238.     if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
  239.     if (!(port->mode & idle)) distnc();
  240.     port->mode = idle;
  241.     return false;
  242.   }
  243.  
  244.   if (match(port->fld[1], "NODE"))
  245.   {
  246.     path[0]->state setbit no_busy;
  247.     distnc();
  248.     port->mode = idle;
  249.     return false;
  250.   }
  251.  
  252. /*
  253.  *  Add known nodes to link table for this node.
  254.  *  Unknown number. Timeout to decide got 'em all.
  255.  */
  256.  
  257.   tcnt = 0;
  258.   if (getit(ntout)) do
  259.   {
  260.     for (i = 0; i < port->flds; i++)
  261.     {
  262.       temp[tcnt] = addnode(port->fld[i]);
  263.       if (temp[tcnt]->seen is NULL) temp[tcnt]->seen = path[0];
  264.       tcnt++;
  265.     }
  266.   }
  267.   while(getit(ntout));
  268.  
  269.   if (port->mode & idle) return false;
  270.  
  271. /*
  272.  *  For each target, get the adjacent nodes toward that target.
  273.  */
  274.  
  275.   for (ti = 0; ti < tcnt; ti++)
  276.   {
  277.     outstr("n "); outstr(temp[ti]->call); outchar('\n');
  278.  
  279. /*
  280.  *  Get line "Routes to ..."
  281.  */
  282.  
  283.     if (!getit(path[0]->hops * nodetime))
  284.     {
  285.       if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
  286.       if (!(port->mode & idle)) distnc();
  287.       port->mode = idle;
  288.       return false;
  289.     }
  290.  
  291.     if (!match(port->fld[1], "ROUTES"))
  292.     {
  293.       while(getit(ntout));
  294.       fprintf(was->fl, "*** Node %s missing routes\n", temp[ti]->call);
  295.     }
  296.     else
  297.     {
  298.       addnode(port->fld[3]); /* Pick up node name ... */
  299.  
  300. /*
  301.  *  Collect all the adjacent node lines.
  302.  *  Unknown number. Timeout to decide got 'em all.
  303.  */
  304.  
  305.       if (getit(ntout)) do
  306.       {
  307.         if (*port->fld[0] is '>') base = 1; else base = 0;
  308.         if (i = atoi(port->fld[base]))
  309.         {
  310.           via = addnode(port->fld[base + 3]);
  311.           if (via->found is NULL) via->found = path[0];
  312.           if (via->hops > path[0]->hops + 1) via->hops = path[0]->hops + 1;
  313.           via->state setbit no_reach;
  314.           fprintf(was->fl, "  To: %-9.9s Via: %s", temp[ti]->call, port->line);
  315.         }
  316.       }
  317.       while(getit(ntout));
  318.     }
  319.  
  320.     if (port->mode & idle) return false;
  321.   }
  322.   return true;
  323. }
  324.  
  325. /*
  326.  *  Trace out the NET/ROM routes.
  327.  */
  328.  
  329. donet()
  330. {
  331.   register int i;
  332.   register PORTS *new;
  333.   NODE  *from, *n;
  334.  
  335.   if (port->mode & sysop) { savecmd(); return; }
  336.  
  337.   if ((new = findport(*port->fld[1])) is NULL) { prtx(mnport); return; }
  338.  
  339.   if ((port->fl = fopen(port->fld[4], "w")) is NULL)
  340.     { nofile(port->fld[4]); return; }
  341.  
  342.   nodecnt = 0;
  343.   nodehd = NULL; nodetl = NULL;
  344.   mp = tmp->scr;
  345.   nodetime = atoi(port->fld[3]);
  346.  
  347. /*
  348.  *  Put the local node into the node table.
  349.  */
  350.  
  351.   addnode(port->fld[2]);
  352.   nodehd->state setbit no_reach;  /* Local node is reachable */
  353.   nodehd->state setbit no_visit;
  354.   nodehd->hops = 1;
  355.   nodehd->found = nodehd;
  356.   nodehd->seen  = nodehd;
  357.  
  358. /*
  359.  *  Remember current port.
  360.  */
  361.  
  362.   was = port;
  363.   ioport(new);
  364.  
  365. /*
  366.  *  Visit the local node.
  367.  */
  368.  
  369.   nodedone = false;
  370.   path[0] = nodehd;
  371.   clnode();
  372.   if (port->mode & idle) { ioport(was); fclose(was->fl); return; }
  373.   getnode();
  374.   distnc();
  375.   port->mode = idle;
  376.  
  377. /*
  378.  *  Visit all nodes the local node knows about.
  379.  */
  380.  
  381.   while (findunode())
  382.   {
  383.     clnode();
  384.     if (!(port->mode & idle))
  385.     {
  386.       if (cnode()) getnode();
  387.       distnc();
  388.       port->mode = idle;
  389.     }
  390.   }
  391.  
  392. /*
  393.  *  Put us back on the port we were on when we got here.
  394.  */
  395.  
  396.   ioport(was);
  397.  
  398. /*
  399.  *  Now we have all the data, print it.
  400.  */
  401.  
  402.   curtim();
  403.   fprintf(was->fl, "\n   Data collected at %s %s\n\n", l_date, l_time);
  404.  
  405.   for (n = nodehd; n isnt NULL; n = n->next)
  406.   {
  407.     if (n->name is NULL)
  408.       fprintf(was->fl, "Node: %-9.9s,     No Alias, %3d hops, seen at %s",
  409.         n->call, n->hops, n->seen->call);
  410.     else
  411.       fprintf(was->fl, "Node: %-9.9s, Alias %-6.6s, %3d hops, seen at %s",
  412.         n->call, n->name, n->hops, n->seen->call);
  413.  
  414.     if (!(n->state & no_reach)) fprintf(was->fl, "  (Not reachable)");
  415.  
  416.     if (n->state & no_busy) fprintf(was->fl, "  (Was busy)");
  417.  
  418.     fprintf(was->fl, "\n");
  419.  
  420.   }
  421.  
  422.   i = (int)(mp - tmp->scr);
  423.   fprintf(was->fl, "%d nodes, %d memory\n", nodecnt, i);
  424.   fclose(was->fl);
  425. }
  426.  
  427. /*
  428.  *  Get a line from the current port.
  429.  *  Handle disconnect and timeout.
  430.  */
  431.  
  432. getit(tm)
  433. int tm;
  434. {
  435.   register short ctime;
  436.  
  437.   ctime = port->ctime;
  438.   port->ctime = tm;
  439.   while(!getdat());
  440.   port->ctime = ctime;
  441.  
  442.   switch(port->mode)
  443.   {
  444.     case timeout :
  445.       port->mode = remote;
  446.       return false;
  447.  
  448.     case forced  :
  449.       nodedone = true;
  450.  
  451.     case discon  :
  452.       distnc();
  453.       port->mode = idle;
  454.       return false;
  455.  
  456.     default :
  457.       port->mode = remote;
  458.       parse();
  459.       return true;
  460.   }
  461. }
  462. #endif
  463.